package com.smart.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.common.utils.DateUtils;
import com.smart.system.domain.Area;
import com.smart.system.domain.AreaLocation;
import com.smart.system.domain.Bucket;
import com.smart.system.service.IAreaService;
import com.smart.system.service.IBucketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.smart.system.mapper.BucketCapacityRecordMapper;
import com.smart.system.domain.BucketCapacityRecord;
import com.smart.system.service.IBucketCapacityRecordService;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 容量记录Service业务层处理
 *
 * @author smart
 * @date 2025-01-03
 */
@Service
public class BucketCapacityRecordServiceImpl extends ServiceImpl<BucketCapacityRecordMapper, BucketCapacityRecord> implements IBucketCapacityRecordService {

    @Autowired
    private IAreaService areaService;

    @Autowired
    private IBucketService bucketService;

    @Override
    public Map<String,Object> get(Date startTIme, Date endTime, List<Integer> bucketIds) {
        List<BucketCapacityRecord> list = this.list(Wrappers.lambdaQuery(BucketCapacityRecord.class)
                        .in(bucketIds!=null&&bucketIds.size()>0,BucketCapacityRecord::getBucketId,bucketIds)
                .ge(BucketCapacityRecord::getCreateTime, startTIme)
                .and(o->o.le(BucketCapacityRecord::getCreateTime, endTime)));
        HashMap<String,Object> hashMap = new HashMap();
        List<Map<String,Object>> maxFluctuations = getBucketInfoData(list);
        hashMap.put("list", maxFluctuations);
        hashMap.put("count", maxFluctuations.size());
        return hashMap;
    }

    @Override
    public Map getBucketMonitor() {
        Map result = new HashMap();
        Map allMap = new HashMap();
        //获取所有区域
        //获取当前日期-5天的日期
        Date startTIme = DateUtils.getDateBefore(new Date(), 5);
        Date endTime = DateUtils.getEndTime();
        Map<String, Object> mapData = get(startTIme, endTime,null);

        List<Map<String,Object>> list = (List<Map<String, Object>>) mapData.get("list");

        //将List中createTime时间格式全部修改为yyyy-MM-dd
        list = list.stream().map(o->{
            o.put("createTime",DateUtils.getAppendTime((Date) o.get("createTime"),"00:00:00"));
            return o;
        }).collect(Collectors.toList());

        // 根据 createTime 进行分组
        Map<Integer, List<Map<String, Object>>> groupedByCreateTime = list.stream()
                .collect(Collectors.groupingBy(o ->  ((Date) o.get("createTime")).getDate()));

        for (Integer integer : groupedByCreateTime.keySet()) {
            List<Map<String, Object>> maps = groupedByCreateTime.get(integer);
            int tempNumber = 0;
            for (Map<String, Object> map : maps) {
                tempNumber+=((List)map.get("number")).size();
            }
            allMap.put(integer,tempNumber);
        }
        //区域集合
        Map areaMap = new HashMap();
        //获取全部区域
        List<Area> areas = areaService.list();
        List<Bucket> buckets = bucketService.list();
        //获取每个区域包含的桶
        for (Area area : areas) {
            List<Integer> includeBuckets = new LinkedList<>();
            for (Bucket bucket : buckets) {
                boolean pointInPolygon = AreaLocation.isPointInPolygon(bucket.getAreaLocation(), area.getAreaLocations());
                if (pointInPolygon) {
                    includeBuckets.add(bucket.getId());
                    //获取当天的垃圾满溢数据
                    List<Map<String, Object>> maps = groupedByCreateTime.get(new Date().getDate());
                    if (maps==null)continue;
                    if (includeBuckets.size()>0) {
                        for (Map<String, Object> map : maps) {
                            if (includeBuckets.contains(map.get("bucketId"))) {
                                Integer number = (Integer) map.get("number");
                                if(areaMap.get(area.getName())==null){
                                    areaMap.put(area.getName(),number);
                                }else{
                                    areaMap.put(area.getName(), (Integer) areaMap.get(area.getName()) + number);
                                }
                            }
                        }
                    }
                }
            }
        }
        result.put("area", areaMap);
        result.put("all", allMap);
        //根据天对List进行分组,只保留到年月日
        return result;
    }

    public Map getMap(Object value1,Object value2){
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("output", value1);
        objectObjectHashMap.put("throughput", value2);
        return objectObjectHashMap;
    }

    private static List<Map<String,Object>> getBucketInfoData(List<BucketCapacityRecord>  params){
        TreeMap<Integer,List<BucketCapacityRecord>> buckets = new TreeMap<>();

        for (BucketCapacityRecord record : params) {
            Integer bucketId = record.getBucketId();
            if (!buckets.containsKey(bucketId)) {
                buckets.put(bucketId, new ArrayList<>());
            }
            buckets.get(bucketId).add(record);
        }
        List<Map<String,Object>> result = new ArrayList<Map<String,Object>>();
        Map<String,Object> tMap = new HashMap<String,Object>();
        for (Integer integer : buckets.keySet()) {
            List<BucketCapacityRecord> bucketCapacityRecords = buckets.get(integer);
            List<Double> processCycles = processCycles(bucketCapacityRecords.stream().map(BucketCapacityRecord::getNumber).collect(Collectors.toList()));
            //获取最后时间
            Date maxCreateTime = null;
            if (bucketCapacityRecords != null && !bucketCapacityRecords.isEmpty()) {
                maxCreateTime = bucketCapacityRecords.stream()
                        .filter(record -> record.getCreateTime() != null)
                        .max(Comparator.comparing(BucketCapacityRecord::getCreateTime))
                        .map(BucketCapacityRecord::getCreateTime)
                        .orElse(null);
            }
            tMap.put("bucketId", integer);
            tMap.put("number", processCycles);
            tMap.put("createTime", maxCreateTime);
            result.add(tMap);
        }

        return result;
    }
    private static List<Double> processCycles(List<Integer> data) {
        List<List<Integer>> cycles = new ArrayList<>();
        List<Integer> currentCycle = new ArrayList<>();

        for (int num : data) {
            if (num == 4 && !currentCycle.isEmpty()) {
                // 将当前周期添加到周期列表中
                cycles.add(new ArrayList<>(currentCycle));
                currentCycle.clear();
                currentCycle.add(4);
            } else if (currentCycle.isEmpty() && num == 4) {
                currentCycle.add(4);
            } else if (!currentCycle.isEmpty()) {
                if (num >= currentCycle.get(currentCycle.size() - 1)) {
                    currentCycle.add(num);
                }
            }
        }

        // 如果当前周期不为空且周期数少于三个，则将当前周期添加到周期列表中
        if (!currentCycle.isEmpty() && cycles.size() < 3) {
            cycles.add(currentCycle);
        }

        // 计算每三个周期的最大值并转换为百分比
        final int minVal = 4;
        final int maxVal = 19;

        List<Double> maxPercentages = new ArrayList<>();
        for (int i = 0; i < cycles.size(); i += 3) {
            int maxValue = Integer.MIN_VALUE;
            for (int j = i; j < Math.min(i + 3, cycles.size()); j++) {
                for (int num : cycles.get(j)) {
                    if (num > maxValue) {
                        maxValue = num;
                    }
                }
            }
            double maxPercentage = ((double) (maxValue - minVal) / (maxVal - minVal)) * 100;
            maxPercentages.add(maxPercentage);
        }

        return maxPercentages;
    }
}